package cc.rengu.igas.opms.core.service.trans.apppay;

import cc.rengu.igas.opms.common.constant.OpmsParamConstant;
import cc.rengu.igas.opms.common.dao.BankSupportCfgMapper;
import cc.rengu.igas.opms.common.dao.impl.BankSupportCfgMapperImpl;
import cc.rengu.igas.opms.common.entity.BankSupportCfgInfo;
import cc.rengu.igas.opms.common.enums.RespCodeEnum;
import cc.rengu.igas.opms.core.service.base.ManageService;
import cc.rengu.igas.opms.facade.bean.BindCardInfo;
import cc.rengu.igas.opms.facade.request.EbankBindCardQueryRequest;
import cc.rengu.igas.opms.facade.response.EbankBindCardQueryResponse;
import cc.rengu.igas.share.core.model.UserInfo;
import cc.rengu.igas.share.core.realize.UserService;
import cc.rengu.igas.share.core.realize.impl.UserServiceImpl;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.dao.SignAcctInfoMapper;
import cc.rengu.oltp.service.common.dao.UserOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.SignAcctInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.UserOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.ChannelCallCfg;
import cc.rengu.oltp.service.common.entity.SignAcctInfo;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.common.entity.UserOrderInfo;
import cc.rengu.oltp.service.common.enums.AcctTypeEnum;
import cc.rengu.oltp.service.common.enums.CheckResultEnum;
import cc.rengu.oltp.service.common.enums.TransStatusEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.model.OrderInfo;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.TransCustomImpl;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.util.ConvertUtil;
import cc.rengu.oltp.utility.util.RedisUtil;
import cc.rengu.oltp.utility.util.StringUtil;
import com.alibaba.fastjson.JSON;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 查询微信手机银行下挂账号
 * 收银台—>支付通道—>ESB
 * T00PM055
 *
 * @author fuyp
 * @date 2020/7/10.
 */
public class EbankBindCardQueryService extends ManageService implements TransCustomImpl {

    @Override
    protected Object bizBeforeCust() throws Exception {
        EbankBindCardQueryRequest ebankBindCardQueryRequest = new EbankBindCardQueryRequest();
        ConvertUtil.convertOutput(ebankBindCardQueryRequest);
        return ebankBindCardQueryRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        //获取请求数据
        EbankBindCardQueryRequest ebankBindCardQueryRequest = (EbankBindCardQueryRequest) request;
        EbankBindCardQueryResponse ebankBindCardQueryResponse = new EbankBindCardQueryResponse();
        //默认设置交易密码未设置
        ebankBindCardQueryResponse.setPasswordFlag("N");
        String rqId = ebankBindCardQueryRequest.getRqId();
        //机构标识
        String instId = ebankBindCardQueryRequest.getHeader().getInstId();
        //用户编号，手机银行userId就是核心客户号
        String userId = ebankBindCardQueryRequest.getUserId();
        String msgSrcId = ebankBindCardQueryRequest.getHeader().getSrcSysId();
        String transChannelId = ebankBindCardQueryRequest.getHeader().getChanlId();
        //交易类型
        String transType = ebankBindCardQueryRequest.getTransType();

        /**  step1： 检查session状态  */
        String session = ebankBindCardQueryRequest.getHeader().getSession();
        UserService userService = new UserServiceImpl();
        UserInfo userInfo = JSON.parseObject(RedisUtil.hashGet(ebankBindCardQueryRequest.getHeader().getSession(), instId + userId), UserInfo.class);
        if (null == userInfo) {
            rglog.error("获取用户信息失败!");
            throw new BizException(RespCodeEnum.USER_NOT_LOGIN_OR_SESSION_IS_EXPIRED.getRespCode(), RespCodeEnum.USER_NOT_LOGIN_OR_SESSION_IS_EXPIRED.getRespDesc());
        }
        /**  step2： 通过核心客户号查询用户，校验用户是否存在  */
        // session中获得核心客户号，此核心客户号来源于登录接口
        // 如果值为空，请检查登录接口
        String coreUserId = userInfo.getUserApexMap().get("coreCustomerId");
        //用户主体
        String userInst = userInfo.getUserInst();
        //签约主体
        String signInst = userInfo.getUserApexMap().get("signInst");
        // 后面程序有使用核心的
        ebankBindCardQueryRequest.setHostCustNo(coreUserId);

        // 根据核心客户号查询出用户编号
        // 是否调用APP6.0接口 Y：是，N:否
        String newMobilePay = "N";
        ebankBindCardQueryRequest.setUserId(userInfo.getUserId());
        //交易密码已设置
        if (!StringUtil.isEmptyOrNull(userInfo.getTransPassword())) {
            ebankBindCardQueryResponse.setPasswordFlag("Y");
        }

        boolean isCreditOpen = checkCreditOpenStatus(instId, ebankBindCardQueryRequest.getMchntOrderId(), msgSrcId, transChannelId, transType);
        rglog.debug("当前行是否支持贷记卡:<{}>", isCreditOpen);

        //查询已签约类型
        this.getBindCardList(ebankBindCardQueryRequest, ebankBindCardQueryResponse, signInst, isCreditOpen);

        SysParamService sysParamService = new SysParamServiceImpl();
        // 查询系统参数手机6.0切换标识
        SysParam newMobilePayParam = sysParamService.getSysParamInfo(instId, OpmsParamConstant.OPMS_SYS_PARAM, OpmsParamConstant.NEW_MOBILE_PAY);

        if (newMobilePayParam != null) {
            newMobilePay = newMobilePayParam.getParamValue();
        }
        // 调用手机APP6.0新接口
        if (OpmsParamConstant.OPMS_PARAM_YES.equals(newMobilePay) &&
                (OpmsParamConstant.MOBILE_BANK_CHANNEL_ID.equals(rqId))) {

            /*准备请求报文 调起esb接口*/
            //TODO 个人账户列表信息查询

            /* 调用esb内管 - 手机账户列表查询手机 */
        } else if (OpmsParamConstant.OPMS_PARAM_YES.equals(newMobilePay) && (OpmsParamConstant.DIRECT_BANK_CHANNEL_ID.equals(rqId))) {
            /*准备请求报文 调起esb接口*/
            //TODO 个人账户列表信息查询



            /* 调用esb内管 - 手机账户列表查询手机 */
        } else if (OpmsParamConstant.MOBILE_BANK_CHANNEL_ID.equals(rqId)) {

            /*准备请求报文 调起esb接口*/
            //TODO 个人账户列表信息查询


        } else if (OpmsParamConstant.DIRECT_BANK_CHANNEL_ID.equals(rqId)) {

            /*准备请求报文 调起esb接口*/
            //TODO 个人账户列表信息查询

        }
        /* 调用esb微信 - 根据网银客户号获取客户账户信息 */
        else if (OpmsParamConstant.MBANK_CHANNEL_ID.equals(rqId) || OpmsParamConstant.O2OBANK_CHANNEL_ID.equals(rqId)) {

            /* 准备请求报文 */
            //TODO 根据客户号获取客户账户信息
        }

        //组装响应
        ebankBindCardQueryResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        ebankBindCardQueryResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());

        BizResponse<EbankBindCardQueryResponse> bizResponse = new BizResponse<>();
        bizResponse.setRspSysId(AppParamConstant.SYS_ID);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(ebankBindCardQueryResponse);
        return bizResponse;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        EbankBindCardQueryResponse ebankBindCardQueryResponse = (EbankBindCardQueryResponse) bizResponse.getResult();
        ConvertUtil.convertInput(ebankBindCardQueryResponse);
    }

    /**
     * 查询的数据库实体类转换为结果响应类
     * Created by liujinan on 2020/4/16.
     */
    private ArrayList<BindCardInfo> convertBindCardInfoInfo(List<SignAcctInfo> signAcctInfos) throws Exception {

        ArrayList<BindCardInfo> bindCardInfos = new ArrayList<>();

        if (signAcctInfos == null || signAcctInfos.isEmpty()) {
            return bindCardInfos;
        }

        for (SignAcctInfo signAcctInfo : signAcctInfos) {
            //查找支持银行列表配置表获取银行名称-银行名称即银行的简称
            String bankName = "";
            BankSupportCfgMapper opmsBankSupportCfgMapper = new BankSupportCfgMapperImpl();
            List<BankSupportCfgInfo> opmsBankSupportCfgInfos = opmsBankSupportCfgMapper.selectOpmsBankSupportCfgByInstIdBankNo(signAcctInfo.getInstId(), signAcctInfo.getSignBankNo());
            if (null == opmsBankSupportCfgInfos || opmsBankSupportCfgInfos.size() == 0) {
                rglog.info("当前机构不存在该支持的银行配置列表，instId:<{}>,bankNo:<{}>", signAcctInfo.getInstId(), signAcctInfo.getSignBankNo());
                bankName = signAcctInfo.getSignBankName();
            } else {
                bankName = opmsBankSupportCfgInfos.get(0).getBankName();
            }

            BindCardInfo bindCardInfo = new BindCardInfo();

            //签约协议号
            bindCardInfo.setSignToken(signAcctInfo.getSignToken());
            //签约类型
            bindCardInfo.setSignType(signAcctInfo.getSignTokenType());
            //签约账户类型
            bindCardInfo.setSignAcctType(signAcctInfo.getSignAcctType());
            //签约银行账号
            bindCardInfo.setSignAcctNo(signAcctInfo.getSignAcctNo());
            //证件类型
            bindCardInfo.setCertType(signAcctInfo.getCertType());
            //证件号码
            bindCardInfo.setCertNo(signAcctInfo.getCertNo());
            //持卡人姓名
            bindCardInfo.setCardHoldName(signAcctInfo.getCardHoldName());
            //预留手机号
            bindCardInfo.setPhoneNo(signAcctInfo.getReserveMobileNo());
            //签约发卡行行号
            bindCardInfo.setSignBankNo(signAcctInfo.getSignBankNo());
            //签约发卡行名称
            bindCardInfo.setSignBankName(bankName);
            //扣款顺序号
            bindCardInfo.setPayIndex(String.valueOf(signAcctInfo.getPayIndex()));
            //单笔限额
            bindCardInfo.setSingleLimitAmt(signAcctInfo.getSingleLimitAmt());
            //当日累计限额
            bindCardInfo.setDayLimitAmt(signAcctInfo.getDayLimitAmt());
            //银行logo路径
            bindCardInfo.setBankLogoUrl("");
            //小额免密限额
            bindCardInfo.setNoPasswordAmt(signAcctInfo.getNoPasswordAmt());
            bindCardInfos.add(bindCardInfo);
        }

        return bindCardInfos;
    }

    /**
     * 客户绑卡列表查询
     *
     * @param ebankBindCardQueryRequest
     * @throws Exception
     */
    private void getBindCardList(EbankBindCardQueryRequest ebankBindCardQueryRequest, EbankBindCardQueryResponse ebankBindCardQueryResponse, String signInst, boolean isCreditOpen) throws Exception {

        if (StringUtil.isEmptyOrNull(ebankBindCardQueryRequest.getUserId())) {
            rglog.error("userId为空，不执行绑卡查询");
            ebankBindCardQueryResponse.setBindCardList(new ArrayList<BindCardInfo>());
        } else {
            String instId = ebankBindCardQueryRequest.getHeader().getInstId();

            String userId = ebankBindCardQueryRequest.getUserId();

            //查询已签约列表
            SignAcctInfoMapper signAcctInfoMapper = new SignAcctInfoMapperImpl();
            List<SignAcctInfo> userSignList = signAcctInfoMapper.selectSignAcctInfoBySignTyUserId(instId, userId, signInst);

            //过滤掉已解约账号
            userSignList = userSignList.stream().filter(item -> item.getSignStatus().trim().equals(OpmsParamConstant.OPMS_PARAM_YES)).collect(Collectors.toList());

            if (!isCreditOpen) {
                //不支持贷记卡，过滤掉签约的贷记卡
                userSignList = userSignList.stream().filter(item -> !item.getSignAcctType().equals(AcctTypeEnum.BANK_CREDIT.getAcctType()) && !item.getSignAcctType().equals(AcctTypeEnum.OTHER_CREDIT.getAcctType())).collect(Collectors.toList());
            }
            //根据交易类型，限定签约卡的类型
            String transType = ebankBindCardQueryRequest.getTransType();

            ebankBindCardQueryResponse.setBindCardList(this.convertBindCardInfoInfo(userSignList));

            rglog.debug("查询已签约账号成功， instId:<{}>, userId:<{}>, signInst:<{}>", instId, userId, signInst);
        }
    }

    /**
     * 校验是否开通贷记卡支付签约功能
     * 先校验行级开关，默认不支持
     * 再校验他行码订单是否支持信用卡，默认支持
     *
     * @param instId
     * @param mchntOrderId
     * @return
     */
    private boolean checkCreditOpenStatus(String instId, String mchntOrderId, String msgSrcId, String transChannelId, String transType) throws Exception {
        //当transType=ScQr时，表示手机银行主扫业务，进行贷记卡开关验证
        if (!StringUtil.isEmptyOrNull(transType) && transType.equals(OpmsParamConstant.SCAN_QR_CODE_TRANS_TYPE)) {
            SysParamService sysParamService = new SysParamServiceImpl();
            SysParam creditParam = sysParamService.getSysParamInfo(instId, OpmsParamConstant.OPMS_PARAM_TYPE, OpmsParamConstant.IS_CREDIT_CARD_OPEN);
            if (creditParam != null && creditParam.getParamValue().equals(OpmsParamConstant.STR_ONE)) {
                rglog.debug("行级开关已打开");
                if (!StringUtil.isEmptyOrNull(mchntOrderId)) {
                    //信用卡行级开关打开，校验订单是否支持信用卡业务，只针对主扫他行码
                    UserOrderInfoMapper userOrderInfoMapper = new UserOrderInfoMapperImpl();
                    UserOrderInfo userOrderInfo = userOrderInfoMapper.selectUserOrderInfoByMchntOrderId(instId, mchntOrderId, msgSrcId, transChannelId);
                    if (userOrderInfo != null && !StringUtil.isEmptyOrNull(userOrderInfo.getOrderType())) {
                        //根据银联规定，此三种订单类型不支持贷记卡支付
                        rglog.debug("订单类型：<{}>", userOrderInfo == null ? "" : userOrderInfo.getOrderType());
                        if ("11".equals(userOrderInfo.getOrderType()) || "15".equals(userOrderInfo.getOrderType())
                                || "31".equals(userOrderInfo.getOrderType())) {
                            return false;
                        }
                    }
                }
                return true;
            }
            //没有设置行级开关，默认为不支持贷记卡
            return false;
        }
        return true;
    }

    @Override
    public ChannelCallCfg channelCallSceneDiscern(Object request, List<ChannelCallCfg> channelCallCfgList) throws Exception {
        return null;
    }

    @Override
    public CheckResultEnum channelCallPreCheck(Object request, ChannelCallCfg channelCallCfg, OrderInfo orderInfo) throws Exception {
        return null;
    }

    @Override
    public TransStatusEnum channelCallResultProc(Object request, ChannelCallCfg channelCallCfg, TransStatusEnum transStatusEnum, Object channelResponse, OrderInfo needUpdateOrderInfo) throws Exception {
        return null;
    }
}